﻿#ifndef MPPENCODE_H
#define MPPENCODE_H

#include <QDebug>
#include <QString>
#include <QByteArray>
#include <memory>

#include "video.h"

#ifdef __cplusplus
extern "C"{
#endif /* __cplusplus */

#include "rockchip/rk_venc_ref.h"
#include "rockchip/mpp_meta.h"
#include "rockchip/rk_venc_cmd.h"
#include "rockchip/mpp_packet.h"
#include <rockchip/vpu_api.h>
#include <rockchip/rk_mpi.h>
#include <rockchip/rk_mpi_cmd.h>
#include <rockchip/rk_type.h>
#include <rockchip/mpp_buffer.h>
#include <rockchip/mpp_frame.h>
#include <rockchip/mpp_err.h>

#ifdef __cplusplus
}
#endif /* __cplusplus */

#define SZ_1K                   (1024)
#define SZ_2K                   (SZ_1K*2)
#define SZ_4K                   (SZ_1K*4)
#define SZ_8K                   (SZ_1K*8)
#define SZ_16K                  (SZ_1K*16)
#define SZ_32K                  (SZ_1K*32)
#define SZ_64K                  (SZ_1K*64)
#define SZ_128K                 (SZ_1K*128)
#define SZ_256K                 (SZ_1K*256)
#define SZ_512K                 (SZ_1K*512)
#define SZ_1M                   (SZ_1K*SZ_1K)
#define SZ_2M                   (SZ_1M*2)
#define SZ_4M                   (SZ_1M*4)
#define SZ_8M                   (SZ_1M*8)
#define SZ_16M                  (SZ_1M*16)
#define SZ_32M                  (SZ_1M*32)
#define SZ_64M                  (SZ_1M*64)
#define SZ_80M                  (SZ_1M*80)
#define SZ_128M                 (SZ_1M*128)

#define MPP_ALIGN(x, a)     (((x)+(a)-1)&~((a)-1))

typedef struct MppEncData_t
{
    // global flow control flag
    uint32_t frm_eos;
    uint32_t pkt_eos;
    uint32_t frame_count;
    uint64_t stream_size;

    // base flow context
    MppCtx ctx;
    MppApi *mpi;
    MppEncPrepCfg prep_cfg;
    MppEncRcCfg rc_cfg;
    MppEncCodecCfg codec_cfg;

    // input / output
    MppBufferGroup buf_grp;
    MppBuffer frm_buf;
    MppBuffer pkt_buf;
    MppEncSeiMode sei_mode;

    uint32_t width;
    uint32_t height;
    uint32_t hor_stride;
    uint32_t ver_stride;
    MppFrameFormat fmt;
    MppCodingType type;

    // resources
    size_t frame_size;

    int32_t gop;
    int32_t fps;
    int32_t bps;
} MppEncData;

class MppEncoder {

public:
   explicit MppEncoder(int width, int height, int fps);
   ~MppEncoder() { deinit(); }

    QByteArray getFrameHeader(void) {
        return m_frameHeader;
    }
    void * getFrameBuffer(void) {
        return mpp_buffer_get_ptr(m_mppEncData.frm_buf);
    }

    MPP_RET encode(QByteArray & pArray);

private:
    //初始化解码信息
    //包括设置编码的格式, 垂直、水平偏移量等信息
    void init();
    //函数调用结束是，释放资源
    void deinit();

private:
    int width = 0, height = 0, fps = 0;
    MppEncData m_mppEncData;
    QByteArray m_frameHeader;
};

#endif // VIDEOENCODE_H
